package cn.cboard.gateway;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Date;
import java.text.DateFormat;
import java.text.ParseException;

/**
 * @author
 * 
 * A Descriptin of a Column
 */
public class ColumnDesc implements Serializable {

	public interface Order {
		public static final int ASCENDING = 0;
		public static final int DESCENDING = 1;
	}

	public interface Type {
		public static final int OBJECT = 0;
		public static final int LONG = 1;
		public static final int INTEGER = 2;
		public static final int STRING = 3;
		public static final int DATE = 4;
		public static final int DECIMAL = 5;
	}

	public static final String[] ORDER_STR = new String[] { "ASC", "DESC" };
	public static final String[] TYPE_STR =
		new String[] {
			"OBJECT",
			"LONG",
			"INTEGER",
			"STRING",
			"DATE",
			"DECIMAL" };

	protected String column;
	protected int order;
	protected int type;
	/**
	 * Constructor for ColumnDesc.
	 */
	public ColumnDesc(String column, int order) {
		this.column = column;
		this.order = order;
		this.type = Type.OBJECT;
	}

	/**
	 * Constructor for ColumnDesc.
	 */
	public ColumnDesc(String column, int order, int type) {
		this.column = column;
		this.order = order;
		this.type = type;

	}

	/**
	 * Constructor for ColumnDesc.
	 */
	public ColumnDesc(String column) {
		this.column = column;
		this.order = Order.ASCENDING;
	}

	/**
	 * Constructor for ColumnDesc.
	 */
	public ColumnDesc() {
		this.column = null;
		this.order = Order.ASCENDING;
	}

	/**
	 * Returns the column.
	 * @return String
	 */
	public String getColumn() {
		return column;
	}

	/**
	 * Returns the order.
	 * @return int
	 */
	public int getOrder() {
		return order;
	}

	/**
	 * Sets the column.
	 * @param column The column to set
	 */
	public void setColumn(String column) {
		this.column = column;
	}

	/**
	 * Sets the order.
	 * @param order The order to set
	 */
	public void setOrder(int order) {
		this.order = order;
	}

	protected static String getSQLOrder(int order) {
		return (order == Order.ASCENDING) ? " ASC " : " DESC ";
	}

	public static String getOperand(int order, boolean inclusive) {
		if (inclusive)
			return (order == Order.DESCENDING) ? " >= " : " <= ";
		else
			return (order == Order.ASCENDING) ? " > " : " < ";

	}

	public Object getParam(Object param) {
		if (param == null)
			return null;

		switch (type) {

			case Type.DECIMAL :
				if (!(param instanceof BigDecimal)) {
					return new BigDecimal(param.toString());
				}
			case Type.DATE :
				if (!(param instanceof Date)) {
					// depending on your driver may need to convert to SQL Date
					// substitite locale date formatting
					try {
						return DateFormat.getInstance().parse(param.toString());
					} catch (ParseException e) {
						System.out.println(
							"Problem parsing date from (" + param + ")" + e.getMessage());
						return null;
					}

				}
			case Type.LONG :
				if (!(param instanceof Long)) {
					return new Long(param.toString());
				}
			case Type.INTEGER :
				if (!(param instanceof Integer)) {
					return new Integer(param.toString());
				}
			case Type.STRING :

				return param.toString();

		}
		return param;
	}

	public String getAsWhere(boolean reverse, boolean inclusive) {
		StringBuffer where = new StringBuffer(column);
		int rorder = (order == 0) ? 1 : 0;
		where.append(
			(!reverse)
				? getOperand(order, inclusive)
				: getOperand(rorder, inclusive));
		where.append(" ? ");
		return where.toString();
	}

	public String getAsOrderBy(boolean reverse) {
		StringBuffer orderBy = new StringBuffer(column);
		int rorder = (order == 0) ? 1 : 0;
		orderBy.append((!reverse) ? getSQLOrder(order) : getSQLOrder(rorder));
		return orderBy.toString();
	}

	public static ColumnDesc toColumnDesc(String str) {
		ColumnDesc d = new ColumnDesc();
		String s = str.trim();
		int idx = s.indexOf(' ');
		if (idx == -1) {
			d.setColumn(s);
		} else {
			d.setColumn(s.substring(0, idx));
			int idx1 = s.indexOf(' ', idx + 1);
			idx1 = (idx1 == -1) ? s.length() : idx1;

			String token = s.substring(idx + 1, idx1);

			for (int i = 0; i < ORDER_STR.length; ++i) {
				if (ORDER_STR[i].equalsIgnoreCase(token)) {
					d.setOrder(i);
					break;
				} //fi
			} //rof

			if (idx1 != -1 && idx1 != s.length()) {
				token = s.substring(idx1 + 1, s.length());
			}

			for (int i = 0; i < TYPE_STR.length; ++i) {
				if (TYPE_STR[i].equalsIgnoreCase(token)) {
					d.setType(i);
					break;
				}
			} // rof
		} //else

		return d;

	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

}
